added Feb 2001 SDK
[windows-sources.git] / shared source / sscli20 / jscript / engine / withobject.cs
blobcb5f286f5653f9cbacd3b812e7f5b556938b7da7
1 // ==++==
2 //
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 //
14 // ==--==
16 namespace Microsoft.JScript {
18 using System;
19 using System.Reflection;
20 using System.Diagnostics;
21 using System.Security;
22 using System.Security.Permissions;
24 internal sealed class WithObject : ScriptObject, IActivationObject{
25 internal Object contained_object;
26 internal bool isKnownAtCompileTime;
27 private bool isSuperType;
29 internal WithObject(ScriptObject parent, Object contained_object)
30 : this(parent, contained_object, false) {
33 internal WithObject(ScriptObject parent, Object contained_object, bool isSuperType)
34 : base(parent) {
35 this.contained_object = contained_object;
36 this.isKnownAtCompileTime = contained_object is Type ||
37 (contained_object is ClassScope && ((ClassScope)contained_object).noExpando) ||
38 (contained_object is JSObject && ((JSObject)contained_object).noExpando);
39 this.isSuperType = isSuperType;
42 public Object GetDefaultThisObject(){
43 return this.contained_object;
46 public FieldInfo GetField(String name, int lexLevel){
47 if (lexLevel <= 0)
48 return null;
49 IReflect ir;
50 if (this.contained_object is IReflect)
51 ir = (IReflect)(this.contained_object);
52 else
53 ir = (IReflect)(Globals.TypeRefs.ToReferenceContext(this.contained_object.GetType()));
54 FieldInfo field = ir.GetField(name, BindingFlags.Instance|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.Public);
55 if (field != null)
56 return new JSWrappedField(field, this.contained_object);
57 PropertyInfo prop = ir.GetProperty(name, BindingFlags.Instance|BindingFlags.Static|BindingFlags.Public);
58 if (prop != null)
59 return new JSPropertyField(prop, this.contained_object);
60 if (this.parent != null && lexLevel > 1){
61 field = ((IActivationObject)this.parent).GetField(name, lexLevel-1);
62 if (field != null)
63 return new JSWrappedField(field, this.parent);
65 return null;
68 public GlobalScope GetGlobalScope(){
69 return ((IActivationObject)this.GetParent()).GetGlobalScope();
72 FieldInfo IActivationObject.GetLocalField(String name){
73 Debug.Assert(false);
74 return null;
77 public override MemberInfo[] GetMember(String name, BindingFlags bindingAttr){ //Never called from outside the engine
78 return this.GetMember(name, bindingAttr, true);
81 internal MemberInfo[] GetMember(String name, BindingFlags bindingAttr, bool forceInstanceLookup){
82 IReflect ir;
83 Type t = null;
84 BindingFlags attr = bindingAttr;
85 if (forceInstanceLookup && this.isSuperType && (bindingAttr & BindingFlags.FlattenHierarchy) == 0) attr |= BindingFlags.Instance;
86 Object obj = this.contained_object;
87 try_again_with_outer_class_instance:
88 if (obj is IReflect){
89 ir = (IReflect)(obj);
90 if (obj is Type && !this.isSuperType)
91 attr &= ~BindingFlags.Instance;
92 }else
93 ir = t = Globals.TypeRefs.ToReferenceContext(obj.GetType());
94 MemberInfo[] members = ir.GetMember(name, attr&~BindingFlags.DeclaredOnly);
95 if (members.Length > 0)
96 return ScriptObject.WrapMembers(members, obj);
97 if (obj is Type && !this.isSuperType)
98 members = Typeob.Type.GetMember(name, BindingFlags.Instance|BindingFlags.Public);
99 if (members.Length > 0)
100 return ScriptObject.WrapMembers(members, obj);
101 if (t != null && t.IsNestedPublic){ //Might happen during call to eval
102 try{
103 new ReflectionPermission(ReflectionPermissionFlag.TypeInformation | ReflectionPermissionFlag.MemberAccess).Assert();
104 FieldInfo outerClassInstance = t.GetField("outer class instance", BindingFlags.NonPublic|BindingFlags.Instance);
105 if (outerClassInstance != null){
106 obj = outerClassInstance.GetValue(obj);
107 goto try_again_with_outer_class_instance;
109 }finally{
110 CodeAccessPermission.RevertAssert();
113 if (members.Length > 0)
114 return ScriptObject.WrapMembers(members, obj);
115 return new MemberInfo[0];
118 public override MemberInfo[] GetMembers(BindingFlags bindingAttr){ //Only called when part of the parent chain of a ClassScope
119 return ((IReflect)this.contained_object).GetMembers(bindingAttr);
122 #if !DEBUG
123 [DebuggerStepThroughAttribute]
124 [DebuggerHiddenAttribute]
125 #endif
126 internal override Object GetMemberValue(String name){
127 Object result = LateBinding.GetMemberValue2(this.contained_object, name);
128 if (!(result is Missing))
129 return result;
130 if (this.parent != null)
131 return this.parent.GetMemberValue(name);
132 return Missing.Value;
135 #if !DEBUG
136 [DebuggerStepThroughAttribute]
137 [DebuggerHiddenAttribute]
138 #endif
139 public Object GetMemberValue(String name, int lexlevel){
140 if (lexlevel <= 0)
141 return Missing.Value;
142 Object result = LateBinding.GetMemberValue2(this.contained_object, name);
143 if (result != Missing.Value)
144 return result;
145 return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel-1);
148 #if !DEBUG
149 [DebuggerStepThroughAttribute]
150 [DebuggerHiddenAttribute]
151 #endif
152 internal override void SetMemberValue(String name, Object value){
153 if (LateBinding.GetMemberValue2(this.contained_object, name) is Missing)
154 ((ScriptObject)this.parent).SetMemberValue(name, value);
155 else
156 LateBinding.SetMemberValue(this.contained_object, name, value);